using System.Collections.Generic;
using AutoChess.Map;
using UnityEngine;
using Yunchang;

namespace AutoChess
{
    abstract partial class GameActor
    {
        private ActorEventDispatcher m_event = new ActorEventDispatcher();
        private ActorTransform m_transform;
        private ActorDisplayCmpt m_display;
        private ActorAnimator m_anim;

        private string m_gameObjectName;

        #region 重载oper

        public static bool operator ==(GameActor obj1, GameActor obj2)
        {
            if (ReferenceEquals(obj1, obj2))
            {
                return true;
            }

            bool isObj1Null = ReferenceEquals(obj1, null) || obj1.IsDestroyed;
            bool isObj2Null = ReferenceEquals(obj2, null) || obj2.IsDestroyed;
            return isObj1Null && isObj2Null;
        }

        public static bool operator !=(GameActor obj1, GameActor obj2)
        {
            return !(obj1 == obj2);
        }

        public override bool Equals(object obj2)
        {
            bool isObj1Null = IsDestroyed;
            bool isObj2Null = ReferenceEquals(obj2, null);
            if (isObj1Null && isObj2Null)
            {
                return true;
            }

            return ReferenceEquals(this, obj2);
        }
        #endregion

        #region 公共变量
        public bool IsDestroyed { get; private set; }
        
        public BattleSide ActorSide { get; private set; }
        
        /// <summary>
        /// 服务器GUID
        /// </summary>
        public long SvrActorId { get; private set; }
        
        /// <summary>
        /// 非独立单元，召唤单位
        /// </summary>
        public long OwnSvrActorId { get; private set; }

        /// <summary>
        /// 死亡倒计时
        /// </summary>
        public float DestoryTime { get; set; }

        public ActorEventDispatcher Event
        {
            get { return m_event; }
        }
        
        public ActorTransform ActorTrans
        {
            get { return m_transform; }
        }

        public GameObject ActorGo
        {
            get { return m_transform.ActorGO; }
        }

        public ActorDisplayCmpt Display
        {
            get { return m_display; }
        }

        public ActorAnimator Animator
        {
            get { return m_anim; }
        }

        public bool IsBattleActor { get; set; }

        public SkillManager SkillMgr { get; private set; }
        
        #endregion

        #region 管理接口

        /// <summary>
        /// 流程：Actor基础组件构建。
        /// 注：GameActor创建子类实体的时候先调用此函数
        /// </summary>
        public void CreateActorBase(long svrActorId, long ownSvrActorId, BattleSide side)
        {
            SvrActorId = svrActorId;
            OwnSvrActorId = ownSvrActorId;
            ActorSide = side;
            
            ///创建基础组件
            m_transform = AddCmpt<ActorTransform>();
            m_display = AddCmpt<ActorDisplayCmpt>();
            m_anim = AddCmpt<ActorAnimator>();

            if (IsBattleActor)
            {
            }
        }

        /// <summary>
        /// 流程：销毁
        /// 注：先回调所有组件的销毁接口，然后清理内存。
        /// </summary>
        public void Destroy()
        {
            m_isDestroyAlling = true;
            BeforeDestroyAllCmpt();
            DestroyAllCmpt();

            IsDestroyed = true;
            m_isDestroyAlling = false;
        }

        /// <summary>
        /// 流程：Actor所有组件创建完毕，进入地图逻辑
        /// </summary>
        public void EnterMap()
        {
            if (BPlatform.IsEditorPlatform())
            {
                ActorTrans.ActorGO.name = GetGameObjectName();
            }

            OnEnterMap();

            for (int i = 0; i < m_listCmpt.Count; i++)
            {
                m_listCmpt[i].CallOnEnterMap();
            }
        }

        #endregion

        #region 拓展接口

        public virtual void OnEnterMap()
        {
            
        }
       
        public virtual void UpdateRunData(Dictionary<int, double> runAttrData)
        {
            
        }

        public virtual ActorAttrData GetAttrData()
        {
            return null;
        }
        public virtual double GetActorMoveSpeed()
        {
            return 5;
        }

        public virtual void SetActorGoParent()
        {
            
        }
        public abstract ActorType GetActorType();

        public virtual string GetGameObjectName()
        {
            if (string.IsNullOrEmpty(m_gameObjectName))
            {
                var actorType = GetActorType();
                m_gameObjectName = string.Format("Actor_Type_{0}_{1}", actorType.ToString(), SvrActorId);
            }

            return m_gameObjectName;
        }

        public virtual string GetActorShortName()
        {
            return "";
        }

        public virtual int GetActorResId()
        {
            return 0;
        }

        public virtual void InitPosition(Vector3 initPos)
        {
            ActorTrans.Position = initPos;
            ActorTrans.Forward = MapDataMgr.Instance.GetInitForward(ActorSide);
        }

        

        public virtual bool NeedCollider()
        {
            return true;
        }
        
        public  virtual void RefreshModel()
        {
        }

        public virtual bool HaveSelectAnim()
        {
            return false;
        }

        public virtual bool HaveSelectedEffect()
        {
            return true;
        }

        //todo BATTLE
        #endregion

        private string GetActorDebugName()
        {
            return GetGameObjectName();
        }
    }
}